﻿using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Dapper.Repositories;
using Abp.Domain.Entities;
using Abp.Domain.Repositories;
using Batman.Cms.Core.Commands;
using Batman.Cms.Core.Tools;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Batman.Cms.Core.Services
{
    public class ServiceBase<T> : ApplicationService where T : Entity<int>
    {
        protected readonly IRepository<T> Repository;

        protected readonly ToolBox Tools;

        public ServiceBase(IRepository<T> repository, ToolBox toolBox)
        {
            Repository = repository;

            Tools = toolBox;
        }

        public T Get(int id)
        {
            return Repository.GetAll().AsNoTracking().FirstOrDefault(t => t.Id == id);
        }

        public TDto Get<TDto>(int id)
        {
            var entity = Repository.GetAll().AsNoTracking().FirstOrDefault(t => t.Id == id);
            return ObjectMapper.Map<TDto>(entity);
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="query"></param>
        /// <param name="page"></param>
        /// <param name="keySelector"></param>
        /// <returns></returns>
        protected PagedResultDto<TSource> ToPaged<TSource, TKey>(IQueryable<TSource> query, PagedResultRequestDto page, Expression<Func<TSource, TKey>> keySelector)
        {
            var total = query.Count();
            var data = query.OrderByDescending(keySelector).Skip(page.SkipCount).Take(page.MaxResultCount).ToList();

            return new PagedResultDto<TSource>(total, data);
        }

        public IDapperRepository<T> DapperRepository { get; set; }

        /// <summary>
        /// 根据配置的sql查询
        /// </summary>
        /// <typeparam name="TTarget"></typeparam>
        /// <param name="mapKey"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public List<TTarget> Query<TTarget>(string mapKey, object parameters) where TTarget : class
        {
            // todo: 验证是否配置AddCommandPoolService
            var query = CommandPool.GetSQL(mapKey);
            if (query == null) throw new Exception("sql map not exits");

            return DapperRepository.Query<TTarget>(query, parameters).ToList();
        }
    }
}
